const express = require('express');
const cors = require('cors');
const jwt = require('jsonwebtoken');
const bcrypt = require('bcryptjs');
const fs = require('fs');
const path = require('path');

const app = express();
const PORT = process.env.PORT || 3000;
const JWT_SECRET = 'campus-vision-secret-key';

// 中间件
app.use(cors());
app.use(express.json());

// 请求日志中间件
app.use((req, res, next) => {
  // 记录请求开始时间
  const startTime = Date.now();
  const timestamp = new Date().toISOString();
  const method = req.method;
  const path = req.path;
  const ip = req.ip;
  
  // 记录请求体（只在非GET请求中记录）
  const body = ['POST', 'PUT', 'PATCH'].includes(method) ? JSON.stringify(req.body) : '';
  
  // 监听响应完成事件
  res.on('finish', () => {
    const endTime = Date.now();
    const responseTime = endTime - startTime;
    const statusCode = res.statusCode;
    
    // 生成日志消息
    const logMessage = `[${timestamp}] ${method} ${path} ${statusCode} ${responseTime}ms ${ip} ${body}`;
    
    // 根据状态码选择日志颜色
    if (statusCode >= 500) {
      console.error(logMessage); // 错误日志用红色
    } else if (statusCode >= 400) {
      console.warn(logMessage); // 警告日志用黄色
    } else {
      console.log(logMessage); // 正常日志用默认颜色
    }
  });
  
  next();
});

// 模拟用户数据
const users = [
  {
    id: 1,
    username: 'admin',
    password: bcrypt.hashSync('password', 8)
  }
];

// 从valid_channels.json文件中读取有效视频源
let allVideoSources = [];
try {
  const validChannelsPath = path.join(__dirname, 'static', 'valid_channels.json');
  const validChannelsData = fs.readFileSync(validChannelsPath, 'utf8');
  const validChannels = JSON.parse(validChannelsData);
  // 只选择https协议的视频源
  allVideoSources = validChannels
    // .filter(channel => channel.url && channel.url.startsWith('https'))
    .map(channel => channel.url);
  console.log(`成功加载 ${allVideoSources.length} 个有效视频源`);
} catch (error) {
  console.error('加载valid_channels.json失败:', error.message);
  // 提供默认视频源作为备份
  allVideoSources = [
    'https://play-live-hls.jxtvcn.com.cn/live-city/tv_jxtv2.m3u8',
    'https://play-live-hls.jxtvcn.com.cn/live-city/tv_jxtv3.m3u8',
    'https://play-live-hls.jxtvcn.com.cn/live-city/tv_jxtv5.m3u8',
    'https://play-live-hls.jxtvcn.com.cn/live-city/tv_jxtv6.m3u8',
    'https://play-live-hls.jxtvcn.com.cn/live-city/tv_nanchang.m3u8',
    'https://lsfb.avap.jilintv.cn/zqvk7vpj/channel/43ea5771aa44421591f9dfd2b71f1b9b/index.m3u8',
    'https://play-qukan.cztv.com/live/1758879019692345.m3u8',
    'https://play-live-hls.jxtvcn.com.cn/live-city/tv_jxtv1.m3u8'
  ];
}

// 生成设备和通道数据的函数
function generateDevices() {
  const deviceTemplates = [
    {
      name: 'zx中学-教学楼A-东',
      capabilities: {soundLightWarning: true},
      channelCount: 2
    },
    {
      name: 'zx中学-操场区域',
      capabilities: {soundLightWarning: true},
      channelCount: 5
    },
    {
      name: 'zx中学-实验楼B',
      capabilities: {soundLightWarning: false},
      channelCount: 1
    },
    {
      name: 'zx中学-体育馆',
      capabilities: {soundLightWarning: true},
      channelCount: 1
    },
    {
      name: 'zx中学-图书馆',
      capabilities: {soundLightWarning: false},
      channelCount: 3
    },
    {
      name: 'zx中学-食堂',
      capabilities: {soundLightWarning: true},
      channelCount: 4
    },
    {
      name: 'zx中学-校门口',
      capabilities: {soundLightWarning: true},
      channelCount: 2
    }
  ];

  return deviceTemplates.map((template, index) => {
    const deviceId = index + 1;
    const channels = [];
    
    // 为每个设备生成通道
    for (let i = 0; i < template.channelCount; i++) {
      const channelId = deviceId * 100 + (i + 1);
      // 循环使用视频源，避免索引越界
      const videoSourceIndex = (deviceId * 10 + i) % allVideoSources.length;
      
      channels.push({
        id: channelId,
        name: `${template.name}-${getChannelLocationName(i)}`,
        url: allVideoSources[videoSourceIndex],
        thumbnailUrl: `https://picsum.photos/200/113?random=${channelId}`,
        capabilities: {
          twoWayAudio: Math.random() > 0.3, // 70%概率支持双向音频
          ptzControl: Math.random() > 0.4  // 60%概率支持PTZ控制
        }
      });
    }
    
    return {
      id: deviceId,
      name: template.name,
      capabilities: template.capabilities,
      channels: channels
    };
  });
}

// 获取通道位置名称
function getChannelLocationName(index) {
  const locations = ['前', '后', '左', '右', '入口', '出口', '全景', '走廊', '楼梯', '教室'];
  return locations[index % locations.length];
}

// 生成设备数据
const devices = generateDevices();

// 统一响应函数
function sendResponse(res, statusCode, data = null, message = '', code = 0) {
  const response = {
    code: statusCode === 200 ? 0 : code || statusCode,
    message: statusCode === 200 && !message ? 'success' : message,
    data: data
  };
  return res.status(statusCode).json(response);
}

// 登录接口
app.post('/api/auth/login', (req, res) => {
  const { username, password } = req.body;

  const user = users.find(u => u.username === username);

  if (!user) {
    return sendResponse(res, 404, null, '用户不存在');
  }

  const isPasswordValid = bcrypt.compareSync(password, user.password);

  if (!isPasswordValid) {
    return sendResponse(res, 401, null, '密码不正确');
  }

  // 生成access token（短期，15分钟）
  const accessToken = jwt.sign({ id: user.id }, JWT_SECRET, { expiresIn: 900 });
  
  // 生成refresh token（长期，30天）
  const refreshToken = jwt.sign({ id: user.id }, JWT_SECRET, { expiresIn: 2592000 });

  sendResponse(res, 200, {
    id: user.id,
    username: user.username,
    accessToken: accessToken,
    refreshToken: refreshToken
  });
});

// 刷新token接口
app.post('/api/auth/refresh', (req, res) => {
  const { refreshToken } = req.body;

  if (!refreshToken) {
    return sendResponse(res, 403, null, '未提供refresh token');
  }

  try {
    const decoded = jwt.verify(refreshToken, JWT_SECRET);
    
    // 检查用户是否存在
    const user = users.find(u => u.id === decoded.id);
    if (!user) {
      return sendResponse(res, 401, null, '用户不存在');
    }

    // 生成新的access token
    const newAccessToken = jwt.sign({ id: user.id }, JWT_SECRET, { expiresIn: 900 });
    const newRefreshToken = jwt.sign({ id: user.id }, JWT_SECRET, { expiresIn: 2592000 });
    
    sendResponse(res, 200, {
      accessToken: newAccessToken,
      refreshToken: newRefreshToken
    });
  } catch (error) {
    return sendResponse(res, 401, null, '无效的refresh token');
  }
});

// 验证Token中间件
const verifyToken = (req, res, next) => {
  const token = req.headers['x-access-token'];

  if (!token) {
    return sendResponse(res, 403, null, '未提供token');
  }

  try {
    const decoded = jwt.verify(token, JWT_SECRET);
    req.userId = decoded.id;
    next();
  } catch (error) {
    return sendResponse(res, 401, null, '未授权');
  }
};

// 获取设备列表接口 - 不返回通道详情，只返回设备基本信息
app.get('/api/devices', verifyToken, (req, res) => {
  const devicesWithoutChannelDetails = devices.map(device => ({
    id: device.id,
    name: device.name,
    thumbnailUrl: `https://picsum.photos/200/113?random=${device.id}`,
    channelCount: device.channels.length
  }));
  sendResponse(res, 200, devicesWithoutChannelDetails);
});

// 获取单个设备详情（包含capabilities）
app.get('/api/devices/:id', verifyToken, (req, res) => {
  const deviceId = parseInt(req.params.id);
  const device = devices.find(d => d.id === deviceId);

  if (!device) {
    return sendResponse(res, 404, null, '设备不存在');
  }

  // 返回设备信息，但不包含通道详情
  sendResponse(res, 200, {
    id: device.id,
    name: device.name,
    thumbnailUrl: `https://picsum.photos/200/113?random=${device.id}`,
    capabilities: device.capabilities,
    channelCount: device.channels.length
  });
});

// 获取单个设备的通道列表
app.get('/api/devices/:id/channels', verifyToken, (req, res) => {
  const deviceId = parseInt(req.params.id);
  const device = devices.find(d => d.id === deviceId);

  if (!device) {
    return sendResponse(res, 404, null, '设备不存在');
  }

  sendResponse(res, 200, device.channels);
});

// 获取单个通道的详情
app.get('/api/devices/:deviceId/channels/:channelId', verifyToken, (req, res) => {
  const deviceId = parseInt(req.params.deviceId);
  const channelId = parseInt(req.params.channelId);
  
  const device = devices.find(d => d.id === deviceId);
  
  if (!device) {
    return sendResponse(res, 404, null, '设备不存在');
  }
  
  const channel = device.channels.find(c => c.id === channelId);
  
  if (!channel) {
    return sendResponse(res, 404, null, '通道不存在');
  }
  
  sendResponse(res, 200, channel);
});

// 启动服务器
app.listen(PORT, () => {
  console.log(`服务器运行在端口 ${PORT}`);
});